﻿using EMC.VISITOR.Core;
using Furion.DependencyInjection;
using Furion.FriendlyException;
using Microsoft.International.Converters.TraditionalChineseToSimplifiedConverter;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using OfficeOpenXml.FormulaParsing.Excel.Functions.DateTime;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using static SKIT.FlurlHttpClient.Wechat.Api.Models.CgibinTagsMembersGetBlackListResponse.Types;
using static SKIT.FlurlHttpClient.Wechat.Api.Models.CVOCRDrivingResponse.Types.CardPosition.Types;

namespace EMC.VISITOR.Application;
/// <summary>
/// 訪客記錄服务
/// </summary>
[ApiDescriptionSettings(ApplicationConst.GroupName, Order = 100)]
public partial class VisitLogService : IDynamicApiController, ITransient
{
    protected readonly SqlSugarRepository<VisitLog> _rep;
    protected readonly SqlSugarRepository<SysDictType> _repDType;
    /// <summary>
    /// 人脸照片、证件照片，身份证照片 Host
    /// </summary>
    protected readonly string currentHost = App.GetConfig<string>("CurrentHost");
    protected readonly string carOutHost = App.GetConfig<string>("CarOutHost");
    public VisitLogService(SqlSugarRepository<VisitLog> rep, SqlSugarRepository<SysDictType> repDType)
    {
        _rep = rep;
        _repDType = repDType;
    }
    #region 代码生成
    /// <summary>
    /// 分页查询訪客記錄
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [AllowAnonymous]
    [ApiDescriptionSettings(Name = "Page")]
    public virtual async Task<SqlSugarPagedList<VisitLogOutput>> Page(VisitLogInput input)
    {
        var context = _rep.AsQueryable().FilterDelete();
        if (context.UseCustomeSelectFlag())
        {
            return await context.CustomToSelect<VisitLog, VisitLogOutput>(input);
        }
        else
        {
            var today = DateTime.Today;
            List<long> queryBuildList = new List<long>();
            if (input.LeaderId.HasValue && input.LeaderId <= 0) //表示是主管只查看带审批的数据
            {
                var _db = _rep.Context;

                var TEMPIDS = _db.MyQueryable<VisitLog>().Where(r => r.VisitTime >= today && r.VisitTime < today.AddDays(2)).Select(r => r.Id).ToList();
                var orgs = await _db.MyQueryable<SysOrg>().ToListAsync();
                if (TEMPIDS.Select(r => r.ToString()).Contains(input.LeaderId.ToString()))
                    queryBuildList = orgs.Where(r => r.Pid == orgs.FirstOrDefault(c => c.Code == CommonConst.StorageCode).Id).OrderBy(r => r.OrderNo).Select(r => r.Id).ToList();
            }
            var orgUsers = await context.Context.MyQueryable<SysUser>()
                .LeftJoin<SysOrg>((u, o) => u.OrgId == o.Id)
                .Select((u, o) => new
                {
                    u.RealName,
                    u.OrgId,
                    OrgName = o.Name
                }).ToListAsync();

            var query = context.CustomWhere(input)
                .WhereIF(!string.IsNullOrWhiteSpace(input.SearchKey), u =>
                    u.Visitor.Contains(input.SearchKey.Trim())
                    || u.VisitSite.Contains(input.SearchKey.Trim())
                    || u.Staff.Contains(input.SearchKey.Trim())
                )
                .WhereIF(!input.Vreason.IsNullOrEmpty(), u => u.Vreason.Contains(input.Vreason.Trim()))
                .WhereIF(input.todayVis.HasValue && input.todayVis.Value, u => u.WaitToEnterTime >= today && u.WaitToEnterTime < today.AddDays(1))
                .WhereIF(input.Type.HasValue, u => u.Type == input.Type)
                .WhereIF(input.TypeList != null && input.TypeList.Count > 0, u => input.TypeList.Contains(u.Type))
                .WhereIF(!string.IsNullOrWhiteSpace(input.Vphone), u => u.Vphone.Contains(input.Vphone))
                .WhereIF(!string.IsNullOrWhiteSpace(input.Visitor), u => u.Visitor.Contains(input.Visitor.Trim()))
                .WhereIF(!string.IsNullOrWhiteSpace(input.IdCard), u => u.IdCard.Contains(input.IdCard))
                .WhereIF(!input.Vcompany.IsNullOrEmpty(), u => u.Vcompany.Contains(input.Vcompany))
                .WhereIF(!input.CarNo.IsNullOrEmpty(), u => u.CarNo.Contains(input.CarNo))
                .WhereIF(!string.IsNullOrWhiteSpace(input.VisitSite), u => u.VisitSite.Contains(input.VisitSite.Trim()))
                .WhereIF(input.DeptIdList != null && input.DeptIdList.Count > 0, u => input.DeptIdList.Contains(u.DeptId))
                .WhereIF(input.DeptId > 0, u => SqlFunc.ToInt64(u.DeptId) == input.DeptId)
                .WhereIF(input.LeaderIdList != null && input.LeaderIdList.Count > 0, u => input.LeaderIdList.Contains(u.LeaderId))
                .WhereIF(input.LeaderId > 0, u => SqlFunc.ToInt64(u.LeaderId) == input.LeaderId)
                .WhereIF(queryBuildList.Count > 0, u => queryBuildList.Contains(u.DeptId.Value) && u.Type == VisitorType.Build)
                .WhereIF(!string.IsNullOrWhiteSpace(input.Staff), u => u.Staff.Contains(input.Staff.Trim()))
                .WhereIF(input.Status.HasValue, u => u.Status == input.Status)
                .WhereIF(input.StatusList != null && input.StatusList.Count > 0, u => input.StatusList.Contains(u.Status))
                //处理外键和TreeSelector相关字段的连接
                .LeftJoin<SysOrg>((u, deptid) => u.DeptId == deptid.Id, SqlSugarConst.GetDdataBaseFullName(typeof(SysOrg)))
                .LeftJoin<SysUser>((u, deptid, leaderid) => u.LeaderId == leaderid.Id, SqlSugarConst.GetDdataBaseFullName(typeof(SysUser)))
                .LeftJoin<SysUser>((u, deptid, leaderid, createuserid) => u.CreateUserId == createuserid.Id, SqlSugarConst.GetDdataBaseFullName(typeof(SysUser)))
                .LeftJoin<SysUser>((u, deptid, leaderid, createuserid, updateuserid) => u.UpdateUserId == updateuserid.Id, SqlSugarConst.GetDdataBaseFullName(typeof(SysUser)))
                .Select((u, deptid, leaderid, createuserid, updateuserid) => new VisitLogOutput
                {
                    Id = u.Id,
                    Type = u.Type,
                    Vphone = u.Vphone,
                    Visitor = u.Visitor,
                    Sex = u.Sex,
                    IdCard = u.IdCard,
                    IdCardImg = u.IdCardImg,
                    VisitTime = u.VisitTime,
                    VendTime = u.VendTime,
                    VisitSite = u.VisitSite,
                    Vcompany = u.Vcompany,
                    Vnum = u.Vnum,
                    Vreason = u.Vreason,
                    Vimg = u.Vimg,
                    HwImg = u.HwImg,
                    VisitArea = u.VisitArea,
                    DocImg = u.DocImg,
                    CarNo = u.CarNo,
                    GoodsInfo = u.GoodsInfo,
                    DeptId = u.DeptId,
                    DeptIdName = deptid.Name,
                    LeaderId = u.LeaderId,
                    LeaderIdRealName = leaderid.RealName,
                    Staff = u.Staff,
                    Iphone = u.Iphone,
                    Status = u.Status,
                    CreateTime = u.CreateTime,
                    UpdateTime = u.UpdateTime,
                    CreateUserId = u.CreateUserId,
                    CreateUserIdRealName = createuserid.RealName,
                    UpdateUserId = u.UpdateUserId,
                    UpdateUserIdRealName = updateuserid.RealName,
                    Position = u.Position,
                    StaffConfirm = u.StaffConfirm,
                    LastLeaderName = u.LastLeaderName,
                    WaitToEnterTime = u.WaitToEnterTime,
                    haImg = u.haImg
                }).OrderByIF(input.Field.IsNullOrEmpty(), u => u.CreateTime, OrderByType.Desc).OrderBy(u => u.UpdateTime, OrderByType.Desc)
    //.Mapper(c => c.VimgAttachment, c => c.Vimg)
    //.Mapper(c => c.DocImgAttachment, c => c.DocImg)
    ;
            if (input.VisitTimeRange != null && input.VisitTimeRange.Count > 0)
            {
                DateTime? start = input.VisitTimeRange[0];
                query = query.WhereIF(start.HasValue, u => u.VisitTime > start);
                if (input.VisitTimeRange.Count > 1 && input.VisitTimeRange[1].HasValue)
                {
                    var end = input.VisitTimeRange[1].Value.AddDays(1);
                    query = query.Where(u => u.VisitTime < end);
                }
            }
            if (input.VendTimeRange != null && input.VendTimeRange.Count > 0)
            {
                DateTime? start = input.VendTimeRange[0];
                query = query.WhereIF(start.HasValue, u => u.VendTime > start);
                if (input.VendTimeRange.Count > 1 && input.VendTimeRange[1].HasValue)
                {
                    var end = input.VendTimeRange[1].Value.AddDays(1);
                    query = query.Where(u => u.VendTime < end);
                }
            }
            query = query.CustomeOrder(input);
            var data = await query.CustomToPagedListAsync(input);
            foreach (var item in data.Items)
            {
                item.Vimg = GetVimg(item.Vimg);
                item.haImg = GetVimg(item.haImg);
                item.IdCardImg = GetVimg(item.IdCardImg);
                item.DocImg = GetDocImg(item.DocImg);
                item.GoodsInfo = GetGoodsInfo(item.GoodsInfo);
                if (!item.LastLeaderName.IsNullOrEmpty() && item.LastLeaderName.Contains("?"))
                    item.LastLeaderName = item.LastLeaderName.Split('?')[0];
                if (!item.LastLeaderName.IsNullOrEmpty())
                    item.LastLeaderName = item.LastLeaderName.Replace("null", null);
                if (item.Type != VisitorType.Driver)
                {
                    item.LeaderIdRealName = string.Join(",", orgUsers.Where(r => r.OrgId == item.DeptId).Select(r => r.RealName).Distinct().ToList());
                }
                else
                {
                    item.LeaderIdRealName = string.Join(",", orgUsers.Where(r => item.VisitArea.Split(',').Contains(r.OrgName)).Select(r => r.RealName).Distinct().ToList());
                }
            }

            return data;
        }
    }

    /// <summary>
    /// 获取施工Flow数据下拉框
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [AllowAnonymous]
    public virtual async Task<SqlSugarPagedList<VisitLogOutput>> PageFlow(VisitLogInput input)
    {
        var _db = _rep.Context;
        var today = DateTime.Today;

        var flows = await _db.MyQueryable<FlowSystemSG>()
                  .Where(u => u.EndDateTime >= today).ToListAsync();

        var list = flows.GroupBy(u => u.supplier_name).Select(u => new VisitLogOutput
        {
            Type = VisitorType.Build,
            Vcompany = u.Key,
            VisitTime = u.Min(r => r.BeginDateTime),
            VendTime = u.Max(r => r.EndDateTime),
            Vnum = u.Sum(r => r.vcou),
            Vreason = string.Join("|", u.Select(r => r.project_name))
        }).ToList();

        return new SqlSugarPagedList<VisitLogOutput>
        {
            Page = 1,
            PageSize = 10000,
            Items = list,
            Total = list.Count,
            TotalPages = list.Count,
            HasNextPage = true,
            HasPrevPage = true
        };
    }

    /// <summary>
    /// 施工人员二维码选择项目下拉框
    /// </summary>
    /// <param name="company">公司名称</param>
    /// <returns></returns>
    [HttpPost]
    [AllowAnonymous]
    public virtual async Task<List<VisitLogOutput>> PageFlowVcompany(string company)
    {
        if (company.IsNullOrEmpty())
        {
            company = company.Replace(" ", "");
        }
        var today = DateTime.Today;
        var _db = _rep.Context;
        var data = await _db.MyQueryable<FlowSystemSG>()
                .Where(flow => flow.supplier_name == company && flow.EndDateTime >= today)
                .Select(flow => new VisitLogOutput
                {
                    Id = flow.Id,
                    Type = VisitorType.Build,
                    VisitTime = flow.BeginDateTime,
                    VendTime = flow.EndDateTime,
                    Status = ProcessStatus.Init,
                    Vcompany = flow.supplier_name,
                    Vreason = flow.project_name,
                    Staff = flow.req_empl_name,
                    Iphone = flow.req_tel,
                    Vnum = flow.vcou,
                    personlistString = flow.personlist,
                    bcpersonlistString = flow.bcpersonlist
                }
               ).ToListAsync();

        foreach (var item in data)
        {
            if (!item.bcpersonlistString.IsNullOrEmpty())
            {
                item.bcpersonlistString = item.bcpersonlistString.Replace(" ", "");
                item.bcpersonlistString = ChineseConverter.Convert(item.bcpersonlistString, ChineseConversionDirection.TraditionalToSimplified);//转简体
            }

            if (!item.personlistString.IsNullOrEmpty())
            {
                item.personlistString = item.personlistString.Replace(" ", "") + (item.bcpersonlistString.IsNullOrEmpty() ? "" : $",{item.bcpersonlistString}");
                item.personlistString = ChineseConverter.Convert(item.personlistString, ChineseConversionDirection.TraditionalToSimplified);//转简体
                item.Persons = item.personlistString.Split(',').ToList();
            }
        }
        return data;
    }

    private VisitLogOutput SGConventToVLog(FlowSystemSG flow)
    {
        VisitLogOutput vlog = new VisitLogOutput();
        vlog.Type = VisitorType.Build;
        vlog.VisitTime = flow.BeginDateTime;
        vlog.VendTime = flow.EndDateTime;
        vlog.Status = ProcessStatus.Init;
        vlog.Vcompany = flow.supplier_name;
        vlog.Vreason = flow.project_name;
        vlog.Staff = flow.req_empl_name;
        vlog.Iphone = flow.req_tel;
        vlog.Vnum = flow.vcou;
        //TODO 自动将访问部门和审核人带出
        //vlog.LeaderId = 111;
        //vlog.DeptId = 1111;
        return vlog;
    }
    [NonAction]
    protected string GetVimg(string vimg)
    {
        if (vimg.IsNullOrEmpty()) return default(string);
        if (currentHost.IsNullOrEmpty()) return vimg;

        var uri = new Uri(vimg);
        return $"{uri.Scheme}://{currentHost}{uri.AbsolutePath}";
    }

    [NonAction]
    protected string GetHwImg(string vimg)
    {
        if (vimg.IsNullOrEmpty()) return default(string);
        if (currentHost.IsNullOrEmpty()) return vimg;

        var uri = new Uri(vimg);
        return $"{uri.Scheme}://{currentHost}{uri.AbsolutePath}";
    }
    class DocImgModel
    {
        public string name { get; set; }
        public string url { get; set; }

        public DateTime? time { get; set; }
    }
    private string GetDocImg(string docImg)
    {
        //if (docImg.IsNullOrEmpty()) return default(string);
        //if (currentHost.IsNullOrEmpty()) return docImg;
        //var ipPorts = CommonUtil.ExtractIPAndPort(docImg);

        //docImg = docImg.Replace("scm.emcks.com","172.16.10.200");
        //if (ipPorts.Count <= 0)
        //    return docImg;
        //return docImg.Replace(ipPorts[0], currentHost);

        if (docImg.IsNullOrEmpty()) return default(string);
        if (currentHost.IsNullOrEmpty()) return docImg;

        List<DocImgModel> list = new List<DocImgModel>();
        var images = JsonConvert.DeserializeObject<List<DocImgModel>>(docImg);
        foreach (DocImgModel img in images)
        {
            if (img.url.Contains("blob")) continue;
            DocImgModel imgTemp = new DocImgModel();
            var uri = new Uri(img.url);
            imgTemp.url = $"{uri.Scheme}://{currentHost}{uri.AbsolutePath}";
            imgTemp.name = img.name;
            list.Add(imgTemp);
        }
        return list.ToJson();
    }
    public string GetGoodsInfo(string goodsInfo)
    {
        if (goodsInfo.IsNullOrEmpty()) return default(string);
        if (currentHost.IsNullOrEmpty()) return goodsInfo;

        DateTime now = DateTime.Now;
        List<DocImgModel> list = new List<DocImgModel>();
        var images = JsonConvert.DeserializeObject<List<DocImgModel>>(goodsInfo);
        foreach (DocImgModel img in images)
        {
            DocImgModel imgTemp = new DocImgModel();
            var uri = new Uri(img.url);
            imgTemp.url = $"{uri.Scheme}://{carOutHost}{uri.AbsolutePath}";
            imgTemp.name = img.name;
            if (!img.time.HasValue)
                imgTemp.time = now;
            else
                imgTemp.time = img.time;

            list.Add(imgTemp);
        }
        return list.ToJson();

        //if (goodsInfo.IsNullOrEmpty()) return default(string);
        //if (currentHost.IsNullOrEmpty()) return goodsInfo;

        //var ipPorts = CommonUtil.ExtractIPAndPort(goodsInfo);
        //if (ipPorts.Count <= 0)
        //    return goodsInfo;

        //return goodsInfo.Replace(ipPorts[0], currentHost);
    }

    string GetHostFromUrl(string url)
    {
        string p = @"(http|https)://(?<domain>[^(:|/]*)";
        Regex reg = new Regex(p, RegexOptions.IgnoreCase);
        Match m = reg.Match(url);
        var Result = m.Groups["domain"].Value;
        return Result;
    }

    /// <summary>
    /// 增加訪客記錄
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Add")]
    public virtual async Task<JRResult<string>> Add(AddVisitLogInput input)
    {
        var entity = input.Adapt<VisitLog>();
        var doSomeResult = await entity.DoSomeThing(_rep.Context);
        if (!doSomeResult.Item1)
            return CustomeResult.Fail<string>(doSomeResult.Item2);
        bool isNeedReplicatings = false;
        string repString = null;
        Expression<Func<VisitLog, bool>> whereExpression = r => true;
        if (!entity.DocImg.IsNullOrEmpty())
        {
            entity.DocImg = entity.DocImg.Replace("\"\\\"", "").Replace("\\\"\"", "").Replace("\\", "").Replace("\"\"", "").Replace("\"[\\", "[").Replace("\"[", "[").Replace("]\"", "]");
        }
        if (!entity.GoodsInfo.IsNullOrEmpty())
        {
            entity.GoodsInfo = entity.GoodsInfo.Replace("\"\\\"", "").Replace("\\\"\"", "").Replace("\\", "").Replace("\"\"", "").Replace("\"[\\", "[").Replace("\"[", "[").Replace("]\"", "]"); ;
        }
        if (isNeedReplicatings)
        {
            isNeedReplicatings = await _rep.IsAnyAsync(whereExpression);
            if (!isNeedReplicatings)
            {
                await _rep.InsertAsync(entity);
            }
            else
            {
                //系统中存在已删除数据，还原数据
                whereExpression = whereExpression.And(r => r.IsDelete == true);
                var exsitModel = await _rep.GetFirstAsync(whereExpression);
                if (exsitModel != null)
                {
                    entity.Id = exsitModel.Id; //还原已删除的数据
                    entity.IsDelete = false;
                    await _rep.UpdateAsync(entity);
                    isNeedReplicatings = false;
                }
            }
        }
        else
        {
            await _rep.InsertAsync(entity);
            await _rep.Context.MyInsertable<VisitLog_History>(entity.Adapt<VisitLog_History>()).ExecuteCommandAsync();
        }
        return new JRResult<string>
        {
            Code = !isNeedReplicatings ? StatusCodes.Status200OK : StatusCodes.Status400BadRequest,
            Message = !isNeedReplicatings ? "新增成功！" : $"系统中存在重复的【{repString}】，不能重复添加！",
            Result = null,
            Type = !isNeedReplicatings ? "success" : "error",
            Extras = UnifyContext.Take(),
            Time = DateTime.Now
        };
    }

    /// <summary>
    /// 删除訪客記錄
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Delete")]
    public virtual async Task Delete(DeleteVisitLogInput input)
    {
        var entity = await _rep.GetFirstAsync(u => u.Id == input.Id) ?? throw Oops.Oh(ErrorCodeEnum.D1002);
        await _rep.FakeDeleteAsync(entity);   //假删除
    }

    /// <summary>
    /// 更新訪客記錄
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Update")]
    public virtual async Task<JRResult<string>> Update(UpdateVisitLogInput input)
    {
        var entity = input.Adapt<VisitLog>();
        var doSomeResult = await entity.DoSomeThing(_rep.Context);
        if (!doSomeResult.Item1)
            return CustomeResult.Fail<string>(doSomeResult.Item2);
        bool isNeedReplicatings = false;
        string repString = null;
        Expression<Func<VisitLog, bool>> whereExpression = r => r.Id != entity.Id;

        if (!entity.DocImg.IsNullOrEmpty())
        {
            entity.DocImg = entity.DocImg.Replace("\"\\\"", "").Replace("\\\"\"", "").Replace("\\", "").Replace("\"\"", "").Replace("\"[\\", "[").Replace("\"[", "[").Replace("]\"", "]"); ;
        }
        if (!entity.GoodsInfo.IsNullOrEmpty())
        {
            entity.GoodsInfo = entity.GoodsInfo.Replace("\"\\\"", "").Replace("\\\"\"", "").Replace("\\", "").Replace("\"\"", "").Replace("\"[\\", "[").Replace("\"[", "[").Replace("]\"", "]"); ;
        }
        if (isNeedReplicatings)
        {
            isNeedReplicatings = await _rep.IsAnyAsync(whereExpression);
            if (!isNeedReplicatings)
            {
                await _rep.AsUpdateable(entity).IgnoreColumns(nameof(VisitLog.IsBeShared), nameof(VisitLog.LastLeaderName), nameof(VisitLog.StaffConfirm), nameof(VisitLog.WaitToEnterTime)).ExecuteCommandAsync();
                await _rep.Context.MyInsertable<VisitLog_History>(entity.Adapt<VisitLog_History>()).IgnoreColumns(nameof(VisitLog.IsBeShared), nameof(VisitLog.LastLeaderName), nameof(VisitLog.StaffConfirm), nameof(VisitLog.WaitToEnterTime)).ExecuteCommandAsync();
                await entity.DoSomeThingSaveChildren(_rep.Context);
            }
        }
        else
        {
            await _rep.AsUpdateable(entity).IgnoreColumns(nameof(VisitLog.IsBeShared), nameof(VisitLog.LastLeaderName), nameof(VisitLog.StaffConfirm), nameof(VisitLog.WaitToEnterTime)).ExecuteCommandAsync();
            await _rep.Context.MyInsertable<VisitLog_History>(entity.Adapt<VisitLog_History>()).IgnoreColumns(nameof(VisitLog.IsBeShared), nameof(VisitLog.LastLeaderName), nameof(VisitLog.StaffConfirm), nameof(VisitLog.WaitToEnterTime)).ExecuteCommandAsync();
            await entity.DoSomeThingSaveChildren(_rep.Context);
        }

        return new JRResult<string>
        {
            Code = !isNeedReplicatings ? StatusCodes.Status200OK : StatusCodes.Status400BadRequest,
            Message = !isNeedReplicatings ? "更新成功！" : $"系统中存在重复的【{repString}】，不能修改！",
            Result = null,
            Type = !isNeedReplicatings ? "success" : "error",
            Extras = UnifyContext.Take(),
            Time = DateTime.Now
        };
    }

    /// <summary>
    /// 保存訪客記錄
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "Save")]
    public virtual async Task<JRResult<string>> Save(UpdateVisitLogInput input)
    {
        var entity = input.Adapt<VisitLog>();
        await entity.SaveDoSomeThing(_rep.Context);
        bool isNeedReplicatings = false;
        string repString = null;
        Expression<Func<VisitLog, bool>> whereExpression = r => r.Id != entity.Id;
        if (isNeedReplicatings)
        {
            isNeedReplicatings = await _rep.IsAnyAsync(whereExpression);
            if (!isNeedReplicatings)
            {
                await _rep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
                await entity.DoSomeThingSaveChildren(_rep.Context);
            }
        }
        else
        {
            await _rep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
            await entity.DoSomeThingSaveChildren(_rep.Context);
        }

        return new JRResult<string>
        {
            Code = !isNeedReplicatings ? StatusCodes.Status200OK : StatusCodes.Status400BadRequest,
            Message = !isNeedReplicatings ? "更新成功！" : $"系统中存在重复的【{repString}】，不能修改！",
            Result = null,
            Type = !isNeedReplicatings ? "success" : "error",
            Extras = UnifyContext.Take(),
            Time = DateTime.Now
        };
    }

    /// <summary>
    /// 保存訪客記錄包含关联表
    /// </summary>
    /// <param name="entity"></param>
    /// <returns></returns>
    [HttpPost]
    [ApiDescriptionSettings(Name = "SaveWithChildren")]
    public virtual async Task<JRResult<string>> SaveWithChildren(VisitLog entity)
    {
        await entity.SaveDoSomeThing(_rep.Context);
        bool isNeedReplicatings = false;
        string repString = null;
        Expression<Func<VisitLog, bool>> whereExpression = r => r.Id != entity.Id;
        if (isNeedReplicatings)
        {
            isNeedReplicatings = await _rep.IsAnyAsync(whereExpression);
            if (!isNeedReplicatings)
            {
                await _rep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
                await entity.DoSomeThingSaveChildren(_rep.Context);
            }
        }
        else
        {
            await _rep.AsUpdateable(entity).IgnoreColumns(ignoreAllNullColumns: true).ExecuteCommandAsync();
            await entity.DoSomeThingSaveChildren(_rep.Context);
        }

        return new JRResult<string>
        {
            Code = !isNeedReplicatings ? StatusCodes.Status200OK : StatusCodes.Status400BadRequest,
            Message = !isNeedReplicatings ? "更新成功！" : $"系统中存在重复的【{repString}】，不能修改！",
            Result = null,
            Type = !isNeedReplicatings ? "success" : "error",
            Extras = UnifyContext.Take(),
            Time = DateTime.Now
        };
    }

    /// <summary>
    /// 获取訪客記錄
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet]
    [AllowAnonymous]
    [ApiDescriptionSettings(Name = "Detail")]
    public virtual async Task<JRResult<VisitLogOutput>> Get([FromQuery] QueryByIdVisitLogInput input)
    {
        var data = await _rep.Context.MyQueryable<VisitLog>()
            .Where(u => u.Id == input.Id)
             .LeftJoin<SysOrg>((u, deptid) => u.DeptId == deptid.Id, SqlSugarConst.GetDdataBaseFullName(typeof(SysOrg)))
            .LeftJoin<SysUser>((u, deptid, leaderid) => u.LeaderId == leaderid.Id, SqlSugarConst.GetDdataBaseFullName(typeof(SysUser)))
            .LeftJoin<SysUser>((u, deptid, leaderid, createuserid) => u.CreateUserId == createuserid.Id, SqlSugarConst.GetDdataBaseFullName(typeof(SysUser)))
            .LeftJoin<SysUser>((u, deptid, leaderid, createuserid, updateuserid) => u.UpdateUserId == updateuserid.Id, SqlSugarConst.GetDdataBaseFullName(typeof(SysUser)))
            .Select((u, deptid, leaderid, createuserid, updateuserid) => new VisitLogOutput
            {
                Id = u.Id,
                Type = u.Type,
                Vphone = u.Vphone,
                Visitor = u.Visitor,
                Sex = u.Sex,
                IdCard = u.IdCard,
                IdCardImg = u.IdCardImg,
                VisitTime = u.VisitTime,
                VendTime = u.VendTime,
                VisitSite = u.VisitSite,
                Vcompany = u.Vcompany,
                Vnum = u.Vnum,
                Vreason = u.Vreason,
                Vimg = u.Vimg,
                HwImg = u.HwImg,
                VisitArea = u.VisitArea,
                DocImg = u.DocImg,
                CarNo = u.CarNo,
                GoodsInfo = u.GoodsInfo,
                DeptId = u.DeptId,
                DeptIdName = deptid.Name,
                LeaderId = u.LeaderId,
                LeaderIdRealName = leaderid.RealName,
                Staff = u.Staff,
                Iphone = u.Iphone,
                Status = u.Status,
                CreateTime = u.CreateTime,
                UpdateTime = u.UpdateTime,
                CreateUserId = u.CreateUserId,
                CreateUserIdRealName = createuserid.RealName,
                UpdateUserId = u.UpdateUserId,
                UpdateUserIdRealName = updateuserid.RealName,
                Position = u.Position,
                LastLeaderName = u.LastLeaderName,
                haImg = u.haImg
            }).FirstAsync();

        if (data != null)
        {
            data.Vimg = GetVimg(data.Vimg);
            data.haImg = GetVimg(data.haImg);
            data.IdCardImg = GetVimg(data.IdCardImg);
            //data.HwImg = GetHwImg(data.HwImg);
            data.DocImg = GetDocImg(data.DocImg);
            data.GoodsInfo = GetGoodsInfo(data.GoodsInfo);
        }
        return CustomeResult.Success<VisitLogOutput>(data);
    }

    [HttpGet]
    [AllowAnonymous]
    [ApiDescriptionSettings(Name = "GetVisit")]
    public virtual async Task<JRResult<VisitLogOutput>> GetVisit([FromQuery] VisitLogInput input)
    {
        if (input == null)
            return CustomeResult.Fail<VisitLogOutput>("查询条件不能为空！");

        var data = await _rep.Context.MyQueryable<VisitLog>()
            .WhereIF(input.IsBeShared.HasValue, u => u.IsBeShared == input.IsBeShared)
            .WhereIF(input.Type.HasValue, u => u.Type == input.Type)
            .WhereIF(!input.Vphone.IsNullOrEmpty(), u => u.Vphone == input.Vphone.Trim())
             .LeftJoin<SysOrg>((u, deptid) => u.DeptId == deptid.Id, SqlSugarConst.GetDdataBaseFullName(typeof(SysOrg)))
            .LeftJoin<SysUser>((u, deptid, leaderid) => u.LeaderId == leaderid.Id, SqlSugarConst.GetDdataBaseFullName(typeof(SysUser)))
            .LeftJoin<SysUser>((u, deptid, leaderid, createuserid) => u.CreateUserId == createuserid.Id, SqlSugarConst.GetDdataBaseFullName(typeof(SysUser)))
            .LeftJoin<SysUser>((u, deptid, leaderid, createuserid, updateuserid) => u.UpdateUserId == updateuserid.Id, SqlSugarConst.GetDdataBaseFullName(typeof(SysUser)))
            .Select((u, deptid, leaderid, createuserid, updateuserid) => new VisitLogOutput
            {
                Id = u.Id,
                Type = u.Type,
                Vphone = u.Vphone,
                Visitor = u.Visitor,
                Sex = u.Sex,
                IdCard = u.IdCard,
                IdCardImg = u.IdCardImg,
                VisitTime = u.VisitTime,
                VendTime = u.VendTime,
                VisitSite = u.VisitSite,
                Vcompany = u.Vcompany,
                Vnum = u.Vnum,
                Vreason = u.Vreason,
                Vimg = u.Vimg,
                HwImg = u.HwImg,
                VisitArea = u.VisitArea,
                DocImg = u.DocImg,
                CarNo = u.CarNo,
                GoodsInfo = u.GoodsInfo,
                DeptId = u.DeptId,
                DeptIdName = deptid.Name,
                LeaderId = u.LeaderId,
                LeaderIdRealName = leaderid.RealName,
                Staff = u.Staff,
                Iphone = u.Iphone,
                Status = u.Status,
                CreateTime = u.CreateTime,
                UpdateTime = u.UpdateTime,
                CreateUserId = u.CreateUserId,
                CreateUserIdRealName = createuserid.RealName,
                UpdateUserId = u.UpdateUserId,
                UpdateUserIdRealName = updateuserid.RealName,
                IsBeShared = u.IsBeShared,
                Position = u.Position,
                LastLeaderName = u.LastLeaderName,
                haImg = u.haImg
            })
            .OrderByDescending(u => u.CreateTime)
            .FirstAsync();


        if (data == null)
        {
            return CustomeResult.Fail<VisitLogOutput>($"根据手机号：{input.Vphone}未找到用户信息！");
        }

        data.Vimg = GetVimg(data.Vimg);
        data.haImg = GetVimg(data.haImg);
        data.IdCardImg = GetVimg(data.IdCardImg);
        //data.HwImg = GetHwImg(data.HwImg);
        data.DocImg = GetDocImg(data.DocImg);
        data.GoodsInfo = GetGoodsInfo(data.GoodsInfo);

        return CustomeResult.Success<VisitLogOutput>(data);
    }

    [HttpGet]
    [AllowAnonymous]
    [ApiDescriptionSettings(Name = "GetExistShare")]
    public virtual async Task<JRResult<Object>> GetExistShare(long isBeShared)
    {
        var data = await _rep.Context.MyQueryable<VisitLog>()
            .Where(u => u.IsBeShared == isBeShared)
            .GroupBy(u => new { u.Vnum, u.IsBeShared })
            .Select(u => new
            {
                Vnum = u.Vnum,
                Count = SqlFunc.AggregateCount(u.IsBeShared)
            }).FirstAsync();

        return CustomeResult.Success<Object>(data);
    }

    /// <summary>
    /// 获取訪客記錄详情
    /// </summary>
    [HttpGet]
    public virtual async Task<dynamic> Info(string tableName, long id)
    {
        var logConfigId = SqlSugarConst.GetDataBaseConfigId(tableName);
        if (logConfigId.IsNullOrEmpty())
            return new { };
        var _db = _rep.AsTenant().GetConnectionScope(logConfigId);
        var tableInfo = SqlSugarConst.GetDdataBaseFullName(tableName);
        var dt = await _db.SqlQueryable<dynamic>($"select * from {tableInfo} where Id={id}").ToListAsync();
        dynamic clay = Clay.Object(dt.FirstOrDefault());
        return TypeHelper.SetDynamicZh(SqlSugarConst.GetModelName(tableName), clay);
    }

    /// <summary>
    /// 获取訪客記錄列表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [HttpGet]
    [ApiDescriptionSettings(Name = "List")]
    public async Task<List<VisitLogOutput>> List([FromQuery] VisitLogInput input)
    {
        var data = await _rep.AsQueryable().Select<VisitLogOutput>().ToListAsync();

        foreach (var item in data)
        {
            item.Vimg = GetVimg(item.Vimg);
            item.haImg = GetVimg(item.haImg);
            item.IdCardImg = GetVimg(item.IdCardImg);
            //item.HwImg = GetHwImg(item.HwImg);
            item.DocImg = GetDocImg(item.DocImg);
            item.GoodsInfo = GetGoodsInfo(item.GoodsInfo);
        }
        return data;
    }

    /// <summary>
    /// 获取部門列表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "SysOrgDeptIdDropdown"), HttpPost]
    [AllowAnonymous]
    public async Task<dynamic> SysOrgDeptIdDropdown(VisitLog model = null)
    {
        var logConfigId = SqlSugarConst.GetDataBaseConfigId(typeof(SysOrg));
        var _db = _rep.AsTenant().GetConnectionScope(logConfigId);
        var query = _db.Queryable<SysOrg>();
        if (query.UseDropDownCustomeSelectFlag())
        {
            return await query.UseDropDownCustomeSelect(model);
        }
        else
        {
            return await query.DropDownQuery()
                    .Select(u => new
                    {
                        Label = u.Name,
                        Value = u.Id,
                        Pid = u.Pid,
                        OrderNo = u.OrderNo,
                        Code = u.Code
                    }
                    ).OrderBy(u => u.OrderNo)
                    .ToListAsync();
        }
    }
    /// <summary>
    /// 获取被訪  人姓名列表
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "SysUserLeaderIdDropdown"), HttpPost]
    [AllowAnonymous]
    public async Task<dynamic> SysUserLeaderIdDropdown(VisitLog model = null)
    {
        var logConfigId = SqlSugarConst.GetDataBaseConfigId(typeof(SysUser));
        var _db = _rep.AsTenant().GetConnectionScope(logConfigId);
        var query = _db.Queryable<SysUser>();
        if (query.UseDropDownCustomeSelectFlag())
        {
            return await query.UseDropDownCustomeSelect(model);
        }
        else
        {
            return await query.DropDownQuery()
                    .Select(u => new
                    {
                        OrgId = u.OrgId,
                        Label = u.RealName,
                        Value = u.Id
                    }
                    ).ToListAsync();
        }
    }

    /// <summary>
    /// 上传人臉頭像
    /// </summary>
    /// <param name="file"></param>
    /// <returns></returns>
    [RequestSizeLimit(1024 * 1024 * 1000)]//设定请求大小为1GB（如需设置请求大小设置此特性）
    [ApiDescriptionSettings(Name = "UploadVimg"), HttpPost]
    [AllowAnonymous]
    public virtual async Task<PropsHttpModel> UploadVimg([Required] IFormFile file)
    {
        var service = App.GetService<SysFileService>();

        string todayString = DateTime.Today.ToString("yyyy-MM-dd");
        var model = await service.UploadFile(file, $"upload/Vimg/{todayString}");

        var _db = _rep.Context;

        HKFaceCheck fackCheck = new HKFaceCheck();
        fackCheck.faceUrl = model?.Url;
        var dbExistFaceUrl = await _db.MyQueryable<HKFaceCheck>().AnyAsync(r => r.faceUrl == fackCheck.faceUrl);
        if (!dbExistFaceUrl)
        {
            if (!fackCheck.faceUrl.Contains("DocImg"))
                await _db.MyInsertable<HKFaceCheck>(fackCheck).ExecuteCommandAsync();
            //TODO发送到消息队列
        }
        return new PropsHttpModel
        {
            fileId = model == null ? 0 : model.Id,
            url = model?.Url,
            name = model == null ? null : $"{model.Id}.{model.Suffix}",
            fileName = model?.FileName,
            home = model?.Url,
            res = "result"
        };
    }
    /// <summary>
    /// 上传證件照片
    /// </summary>
    /// <param name="file"></param>
    /// <returns></returns>
    [RequestSizeLimit(1024 * 1024 * 1000)]//设定请求大小为1GB（如需设置请求大小设置此特性）
    [ApiDescriptionSettings(Name = "UploadIdCardImg"), HttpPost]
    [AllowAnonymous]
    public virtual async Task<PropsHttpModel> UploadIdCardImg([Required] IFormFile file)
    {
        string todayString = DateTime.Today.ToString("yyyy-MM-dd");
        var service = App.GetService<SysFileService>();
        var model = await service.UploadFile(file, $"upload/IdCardImg/{todayString}");
        return new PropsHttpModel
        {
            fileId = model == null ? 0 : model.Id,
            url = model?.Url,
            name = model == null ? null : $"{model.Id}.{model.Suffix}",
            fileName = model?.FileName,
            home = model?.Url,
            res = "result"
        };
    }

    [RequestSizeLimit(1024 * 1024 * 1000)]//设定请求大小为1GB（如需设置请求大小设置此特性）
    [ApiDescriptionSettings(Name = "UploadHaImg"), HttpPost]
    [AllowAnonymous]
    public virtual async Task<PropsHttpModel> UploadHaImg([Required] IFormFile file)
    {
        string todayString = DateTime.Today.ToString("yyyy-MM-dd");
        var service = App.GetService<SysFileService>();
        var model = await service.UploadFile(file, $"upload/HaImg/{todayString}");
        return new PropsHttpModel
        {
            fileId = model == null ? 0 : model.Id,
            url = model?.Url,
            name = model == null ? null : $"{model.Id}.{model.Suffix}",
            fileName = model?.FileName,
            home = model?.Url,
            res = "result"
        };
    }

    /// <summary>
    /// 上传行驶证等照片
    /// </summary>
    /// <param name="file"></param>
    /// <returns></returns>
    [RequestSizeLimit(1024 * 1024 * 1000)]//设定请求大小为1GB（如需设置请求大小设置此特性）
    [ApiDescriptionSettings(Name = "UploadDocImg"), HttpPost]
    [AllowAnonymous]
    public virtual async Task<PropsHttpModel> UploadDocImg([Required] IFormFile file)
    {
        string todayString = DateTime.Today.ToString("yyyy-MM-dd");
        var service = App.GetService<SysFileService>();
        var model = await service.UploadFile(file, $"upload/DocImg/{todayString}");
        return new PropsHttpModel
        {
            fileId = model == null ? 0 : model.Id,
            url = model?.Url,
            name = model == null ? null : $"{model.Id}.{model.Suffix}",
            fileName = model?.FileName,
            home = model?.Url,
            res = "result"
        };
    }
    /// <summary>
    /// 上传物品信息
    /// </summary>
    /// <param name="file"></param>
    /// <returns></returns>
    [RequestSizeLimit(1024 * 1024 * 1000)]//设定请求大小为1GB（如需设置请求大小设置此特性）
    [ApiDescriptionSettings(Name = "UploadGoodsInfo"), HttpPost]
    [AllowAnonymous]
    public virtual async Task<PropsHttpModel> UploadGoodsInfo([Required] IFormFile file)
    {
        string todayString = DateTime.Today.ToString("yyyy-MM-dd");
        var service = App.GetService<SysFileService>();
        var model = await service.UploadFile(file, $"upload/GoodsInfo/{todayString}");
        return new PropsHttpModel
        {
            fileId = model == null ? 0 : model.Id,
            url = model?.Url,
            name = model == null ? null : $"{model.Id}.{model.Suffix}",
            fileName = model?.FileName,
            home = model?.Url,
            res = "result"
        };
    }


    /// <summary>
    /// 导出訪客記錄
    /// </summary>
    /// <returns></returns>
    [ApiDescriptionSettings(Name = "Export"), NonUnify]
    public virtual async Task<IActionResult> Export(VisitLogInput input)
    {
        var context = _rep.AsQueryable().FilterDelete();
        if (context.UseCustomeSelectFlag())
        {
            var list = await context.CustomToSelectExport<VisitLog, ExportImportVisitLogDto>(input);
            IExcelExporter excelExporter = new ExcelExporter();
            var res = await excelExporter.ExportAsByteArray(list);
            return new FileStreamResult(new MemoryStream(res), "application/octet-stream") { FileDownloadName = DateTime.Now.ToString("yyyyMMddHHmm") + "生产模式切换记录表.xlsx" };
        }
        else
        {
            var today = DateTime.Today;
            List<long> queryBuildList = new List<long>();
            if (input.LeaderId.HasValue && input.LeaderId <= 0) //表示是主管只查看带审批的数据
            {
                var _db = _rep.Context;

                var TEMPIDS = _db.MyQueryable<VisitLog>().Where(r => r.VisitTime >= today && r.VisitTime < today.AddDays(2)).Select(r => r.Id).ToList();
                var orgs = await _db.MyQueryable<SysOrg>().ToListAsync();
                if (TEMPIDS.Select(r => r.ToString()).Contains(input.LeaderId.ToString()))
                    queryBuildList = orgs.Where(r => r.Pid == orgs.FirstOrDefault(c => c.Code == CommonConst.StorageCode).Id).OrderBy(r => r.OrderNo).Select(r => r.Id).ToList();
            }
            var orgUsers = await context.Context.MyQueryable<SysUser>()
                .LeftJoin<SysOrg>((u, o) => u.OrgId == o.Id)
                .Select((u, o) => new
                {
                    u.RealName,
                    u.OrgId,
                    OrgName = o.Name
                }).ToListAsync();

            var query = context.CustomWhere(input)
                .WhereIF(!string.IsNullOrWhiteSpace(input.SearchKey), u =>
                    u.Visitor.Contains(input.SearchKey.Trim())
                    || u.VisitSite.Contains(input.SearchKey.Trim())
                    || u.Staff.Contains(input.SearchKey.Trim())
                )
                .WhereIF(!input.Vreason.IsNullOrEmpty(), u => u.Vreason.Contains(input.Vreason.Trim()))
                .WhereIF(input.todayVis.HasValue && input.todayVis.Value, u => u.WaitToEnterTime >= today && u.WaitToEnterTime < today.AddDays(1))
                .WhereIF(input.Type.HasValue, u => u.Type == input.Type)
                .WhereIF(input.TypeList != null && input.TypeList.Count > 0, u => input.TypeList.Contains(u.Type))
                .WhereIF(!string.IsNullOrWhiteSpace(input.Vphone), u => u.Vphone.Contains(input.Vphone))
                .WhereIF(!string.IsNullOrWhiteSpace(input.Visitor), u => u.Visitor.Contains(input.Visitor.Trim()))
                .WhereIF(!string.IsNullOrWhiteSpace(input.IdCard), u => u.IdCard.Contains(input.IdCard))
                .WhereIF(!input.Vcompany.IsNullOrEmpty(), u => u.Vcompany.Contains(input.Vcompany))
                .WhereIF(!input.CarNo.IsNullOrEmpty(), u => u.CarNo.Contains(input.CarNo))
                .WhereIF(!string.IsNullOrWhiteSpace(input.VisitSite), u => u.VisitSite.Contains(input.VisitSite.Trim()))
                .WhereIF(input.DeptIdList != null && input.DeptIdList.Count > 0, u => input.DeptIdList.Contains(u.DeptId))
                .WhereIF(input.DeptId > 0, u => SqlFunc.ToInt64(u.DeptId) == input.DeptId)
                .WhereIF(input.LeaderIdList != null && input.LeaderIdList.Count > 0, u => input.LeaderIdList.Contains(u.LeaderId))
                .WhereIF(input.LeaderId > 0, u => SqlFunc.ToInt64(u.LeaderId) == input.LeaderId)
                .WhereIF(queryBuildList.Count > 0, u => queryBuildList.Contains(u.DeptId.Value) && u.Type == VisitorType.Build)
                .WhereIF(!string.IsNullOrWhiteSpace(input.Staff), u => u.Staff.Contains(input.Staff.Trim()))
                .WhereIF(input.Status.HasValue, u => u.Status == input.Status)
                .WhereIF(input.StatusList != null && input.StatusList.Count > 0, u => input.StatusList.Contains(u.Status))
                //处理外键和TreeSelector相关字段的连接
                .LeftJoin<SysOrg>((u, deptid) => u.DeptId == deptid.Id, SqlSugarConst.GetDdataBaseFullName(typeof(SysOrg)))
                .LeftJoin<SysUser>((u, deptid, leaderid) => u.LeaderId == leaderid.Id, SqlSugarConst.GetDdataBaseFullName(typeof(SysUser)))
                .LeftJoin<SysUser>((u, deptid, leaderid, createuserid) => u.CreateUserId == createuserid.Id, SqlSugarConst.GetDdataBaseFullName(typeof(SysUser)))
                .LeftJoin<SysUser>((u, deptid, leaderid, createuserid, updateuserid) => u.UpdateUserId == updateuserid.Id, SqlSugarConst.GetDdataBaseFullName(typeof(SysUser)))
                .Select((u, deptid, leaderid, createuserid, updateuserid) => new ExportImportVisitLogDto
                {
                    Type = u.Type,
                    Vphone = u.Vphone,
                    Visitor = u.Visitor,
                    Sex = u.Sex,
                    IdCard = u.IdCard,
                    IdCardImg = u.IdCardImg,
                    VisitTime = u.VisitTime,
                    VendTime = u.VendTime,
                    VisitSite = u.VisitSite,
                    Vcompany = u.Vcompany,
                    Vnum = u.Vnum,
                    Vreason = u.Vreason,
                    Vimg = u.Vimg,
                    VisitArea = u.VisitArea,
                    DocImg = u.DocImg,
                    CarNo = u.CarNo,
                    GoodsInfo = u.GoodsInfo,
                    DeptId = u.DeptId,
                    DeptIdName = deptid.Name,
                    LeaderId = u.LeaderId,
                    LeaderIdRealName = leaderid.RealName,
                    Staff = u.Staff,
                    Iphone = u.Iphone,
                    Status = u.Status,
                    Position = u.Position,
                    LastLeaderName = u.LastLeaderName,
                    WaitToEnterTime = u.WaitToEnterTime,
                    CreateTime = u.CreateTime,
                    UpdateTime = u.UpdateTime,
                    haImg = u.haImg
                }).OrderByIF(input.Field.IsNullOrEmpty(), u => u.CreateTime, OrderByType.Desc).OrderBy(u => u.UpdateTime, OrderByType.Desc)
    //.Mapper(c => c.VimgAttachment, c => c.Vimg)
    //.Mapper(c => c.DocImgAttachment, c => c.DocImg)
    ;
            if (input.VisitTimeRange != null && input.VisitTimeRange.Count > 0)
            {
                DateTime? start = input.VisitTimeRange[0];
                query = query.WhereIF(start.HasValue, u => u.VisitTime > start);
                if (input.VisitTimeRange.Count > 1 && input.VisitTimeRange[1].HasValue)
                {
                    var end = input.VisitTimeRange[1].Value.AddDays(1);
                    query = query.Where(u => u.VisitTime < end);
                }
            }
            if (input.VendTimeRange != null && input.VendTimeRange.Count > 0)
            {
                DateTime? start = input.VendTimeRange[0];
                query = query.WhereIF(start.HasValue, u => u.VendTime > start);
                if (input.VendTimeRange.Count > 1 && input.VendTimeRange[1].HasValue)
                {
                    var end = input.VendTimeRange[1].Value.AddDays(1);
                    query = query.Where(u => u.VendTime < end);
                }
            }

            query = query.CustomeOrder(input);
            var list = await query.ToListAsync();

            foreach (var item in list)
            {
                item.Vimg = GetVimg(item.Vimg);
                item.haImg = GetVimg(item.haImg);
                //item.HwImg = GetHwImg(item.HwImg);
                item.IdCardImg = GetVimg(item.IdCardImg);
                item.DocImg = GetDocImg(item.DocImg);
                item.GoodsInfo = GetGoodsInfo(item.GoodsInfo);
                if (!item.LastLeaderName.IsNullOrEmpty() && item.LastLeaderName.Contains("?"))
                    item.LastLeaderName = item.LastLeaderName.Split('?')[0];
                if (!item.LastLeaderName.IsNullOrEmpty())
                    item.LastLeaderName = item.LastLeaderName.Replace("null", null);
                if (item.Type != VisitorType.Driver)
                {
                    item.LeaderIdRealName = string.Join(",", orgUsers.Where(r => r.OrgId == item.DeptId).Select(r => r.RealName).Distinct().ToList());
                }
                else
                {
                    item.LeaderIdRealName = string.Join(",", orgUsers.Where(r => item.VisitArea.Split(',').Contains(r.OrgName)).Select(r => r.RealName).Distinct().ToList());
                }
            }
            IExcelExporter excelExporter = new ExcelExporter();
            var res = await excelExporter.ExportAsByteArray(list);
            return new FileStreamResult(new MemoryStream(res), "application/octet-stream") { FileDownloadName = DateTime.Now.ToString("yyyyMMddHHmm") + "訪客記錄.xlsx" };
        }
    }

    /// <summary>
    /// 导入
    /// </summary>
    /// <param name="file"></param>
    /// <returns></returns>
    [HttpPost]
    public virtual async Task<JRResult<string>> Import(IFormFile file)
    {
        IImporter Importer = new ExcelImporter();
        var importData = await Importer.Import<ExportImportVisitLogDto>(file.OpenReadStream());
        if (importData.HasError == true) { return CustomeResult.Fail<string>("导入错误"); }
        if (importData.Exception != null) { return CustomeResult.Fail<string>(importData.Exception.ToString()); }
        if (importData.RowErrors.Count > 0) { return CustomeResult.Fail<string>(JSON.Serialize(importData.RowErrors)); }
        if (importData.Data == null) { return CustomeResult.Fail<string>("导入的数据量不能为空！"); }
        if (importData.Data.Count <= 0) { return CustomeResult.Fail<string>("导入的数据量为0个！"); }

        var models = importData.Data.Adapt<List<VisitLog>>();
        bool isNeedReplicatings = false;
        string repString = null;
        Expression<Func<VisitLog, bool>> whereExpression = r => true;
        if (isNeedReplicatings)
        {
            isNeedReplicatings = await _rep.IsAnyAsync(whereExpression);

            if (!isNeedReplicatings)
            {
                await _rep.AsInsertable(models).ExecuteCommandAsync();
            }
            else
                return CustomeResult.Fail<string>(repString);
        }
        else
        {
            await _rep.AsInsertable(models).ExecuteCommandAsync();
        }

        return CustomeResult.SuccessNotShowMessage<string>();
    }


    /// <summary>
    /// 模板下载
    /// </summary>
    /// <returns></returns>
    [AllowAnonymous]
    [HttpGet]
    public virtual async Task<IActionResult> TemplateDown()
    {
        IImporter Importer = new ExcelImporter();
        var template = await Importer.GenerateTemplateBytes<ExportImportVisitLogDto>();
        return new FileStreamResult(new MemoryStream(template), "application/octet-stream") { FileDownloadName = DateTime.Now.ToString("yyyyMMddHHmm") + "訪客記錄导入模板.xlsx" };
    }
    #endregion
}

